package com.yuke.cloud.service.uac.service.impl;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.base.dto.LoginAuthDto;
import com.yuke.cloud.common.base.enums.ErrorCodeEnum;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.service.api.uac.exceptions.UacBizException;
import com.yuke.cloud.service.uac.dao.AccRoleMapper;
import com.yuke.cloud.service.uac.dao.AccRoleMenuMapper;
import com.yuke.cloud.service.uac.dto.RoleBindMenuDto;
import com.yuke.cloud.service.uac.entity.*;
import com.yuke.cloud.service.uac.service.AccMenuService;
import com.yuke.cloud.service.uac.service.AccPermissionService;
import com.yuke.cloud.service.uac.service.AccRoleMenuService;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.service.uac.service.AccRoleService;
import com.yuke.cloud.service.uac.utils.BindAuthUtil;
import com.yuke.cloud.service.uac.utils.TreeUtil;
import com.yuke.cloud.service.uac.vo.BindAuthVo;
import com.yuke.cloud.service.uac.vo.MenuVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Set;


/**
 * Created by wg on 2018/10/31.
 */
@Service
@Transactional
public class AccRoleMenuServiceImpl extends BaseService<AccRoleMenu> implements AccRoleMenuService {
    @Resource
    private AccRoleMenuMapper accRoleMenuMapper;
    @Resource
    private AccRoleService accRoleService;
    @Resource
    private AccMenuService accMenuService;

    @Override
    public void deleteByRoleId(Long roleId) {
        if (roleId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10012001);
        }
//        AccRoleMenu roleMenu = new AccRoleMenu();
//        roleMenu.setRoleId(roleId);
//        accRoleMenuMapper.delete(roleMenu);

        Example example = new Example(AccRoleMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId", roleId);
        accRoleMenuMapper.deleteByExample(example);
    }

    @Override
    public void deleteByRoleIdList(final List<Long> roleIdList) {

        Example example = new Example(AccRoleMenu.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("roleId", roleIdList);
        int result = accRoleMenuMapper.deleteByExample(example);
//        if (result < roleIdList.size()) {
//            throw new UacBizException(ErrorCodeEnum.UAC10012007, Joiner.on(GlobalConstant.Symbol.COMMA).join(roleIdList));
//        }
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public List<Long> getCheckedMenuList(Long roleId) {
        if (roleId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10012001);
        }
        return accRoleMenuMapper.getCheckedMenuList(roleId);
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public List<AccRoleMenu> listByRoleId(Long roleId) {
        if (roleId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10012001);
        }
        AccRoleMenu roleMenu = new AccRoleMenu();
        roleMenu.setRoleId(roleId);
        return accRoleMenuMapper.select(roleMenu);
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public BindAuthVo getMenuTreeByRoleId(Long roleId) {
        BindAuthVo bindAuthVo = new BindAuthVo();
        Preconditions.checkArgument(roleId != null, ErrorCodeEnum.UAC10012001.msg());

        AccRole roleById = accRoleService.getRoleById(roleId);
        if (roleById == null) {
            logger.error("找不到角色信息 roleId={}", roleId);
            throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
        }

        // 查询所有的菜单信息
        List<AccMenu> accMenus = accMenuService.selectAll();
        // 合并菜单和按钮权限 递归生成树结构

        List<MenuVo> menuVoList = BindAuthUtil.getAuthList(accMenus, null);

        List<MenuVo> tree = TreeUtil.getChildMenuVos(menuVoList, 0L);

        // 获取所有绑定的菜单和按钮权限Id集合
        List<Long> checkedAuthList = this.getCheckedMenuList(roleId);

        bindAuthVo.setAuthTree(tree);
        bindAuthVo.setCheckedAuthList(checkedAuthList);

        return bindAuthVo;
    }

    private void insert(Long roleId, Set<Long> menuIdList) {
        if (roleId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10012001);
        }
        AccRoleMenu accRoleMenu = new AccRoleMenu();
        accRoleMenu.setRoleId(roleId);
        for (Long menuId : menuIdList) {
            accRoleMenu.setRoleMenuId(super.generateId());
            accRoleMenu.setMenuId(menuId);
            accRoleMenuMapper.insertSelective(accRoleMenu);
        }
    }

    @Override
    public void bindMenu(RoleBindMenuDto roleBindMenuDto, LoginAuthDto loginAuthDto) {

        Long roleId = roleBindMenuDto.getRoleId();
        Set<Long> menuIdList = roleBindMenuDto.getMenuIdList();

        if (roleId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10012001);
        }

        // mod by wg 20181220 增加&& loginAuthDto.getUserId() != GlobalConstant.Sys.SUPER_MANAGER_USER_ID条件
        if (Objects.equals(roleId, GlobalConstant.Sys.SUPER_MANAGER_ROLE_ID)
                && loginAuthDto.getUserId() != GlobalConstant.Sys.SUPER_MANAGER_USER_ID) {
            logger.error("越权操作, 超级管理员用户不允许操作");
            throw new UacBizException(ErrorCodeEnum.UAC10011023);
        }

        AccRole accRole = accRoleService.getRoleById(roleId);

        if (accRole == null) {
            logger.error("找不到角色信息. roleId={}", roleId);
            throw new UacBizException(ErrorCodeEnum.UAC10012005, roleId);
        }

        // TODO 校验参数的合法性(暂时不写了,也就是校验菜单和权限是否存在)
        List<AccRoleMenu> uacRoleMenuList = this.listByRoleId(roleId);

        if (PublicUtil.isNotEmpty(uacRoleMenuList)) {
            this.deleteByRoleId(roleId);
        }

        // menuSet actionIdList 如果为空则 取消该角色所有权限
        if (PublicUtil.isEmpty(menuIdList)) {
            logger.error("传入菜单权限Id为空, 取消菜单权限");
        } else {
            // 绑定菜单
            this.insert(roleId, menuIdList);

        }
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public List<String> getOwnMenuUrlList(Long userId) {
        if (userId == null) {
            throw new UacBizException(ErrorCodeEnum.UAC10011001);
        }
        return accRoleMenuMapper.getOwnMenuUrlList(userId);
    }

}
